#include "DbClient.h"
#include <stdexcept>
#include <iostream>
#include <sstream>

// 静态成员定义
DbClient* DbClient::instance_ = nullptr;
std::mutex DbClient::mutex_;

// 获取单例实例
DbClient& DbClient::getInstance(const std::string& uri, bool insecure) {
    std::lock_guard<std::mutex> lock(mutex_);
    
    // ✅ 第一次调用时初始化库
    if (instance_ == nullptr) {
        int err = neo4j_client_init();
        if (err != 0) {
            throw std::runtime_error("Failed to initialize libneo4j-client library");
        }
        
        instance_ = new DbClient(uri, insecure);
        std::cout << "init success" << '\n';
    }
    return *instance_;
}

// 私有构造函数
DbClient::DbClient(const std::string& uri, bool insecure)
    : uri_(uri), insecure_(insecure) {
    connect();
}

// 析构函数 - 自动关闭连接
DbClient::~DbClient() {
    close();
    std::lock_guard<std::mutex> lock(mutex_);
    delete instance_;
    instance_ = nullptr;
}

void DbClient::connect() {
    if (connection_) return;

    // 直接使用neo4j_connect，不使用配置对象（简化版本）
    unsigned int flags = insecure_ ? NEO4J_INSECURE : 0;

    connection_ = neo4j_connect(uri_.c_str(), nullptr, flags);

    if (!connection_) {
        std::ostringstream oss;
        oss << "neo4j_connect() failed: errno=" << errno;
        throw std::runtime_error(oss.str());
    }
    std::cout << "connect success" << '\n';
}

// 关闭连接
void DbClient::close() {
    if (connection_ != nullptr) {
        neo4j_close(connection_);
        connection_ = nullptr;
    }
}

// 执行 Cypher 查询
neo4j_result_stream_t* DbClient::run(const char *cypher, neo4j_value_t params) {
    if (connection_ == nullptr) {
        throw std::runtime_error("Not connected to Neo4j database");
    }
    neo4j_result_stream_t* results = neo4j_run(connection_, cypher, params);
    if (results == nullptr) {
        throw std::runtime_error("Failed to execute Cypher query");
    }
    return results;
}